0

I am struggling to regain control of indentation for certain filetypes, particularly when pasting code. I end up with what I call "cascading indentation" which is nearly unreadable.

I've run into this problem in the past, and have sort of limped my way through getting it to work. Today I am trying to understand the problem in a complete and systematic way.

For an example, if I copy this to my clipboard...

proc dumpDut1Stats {VARNAME_statsKeyedList} {
    upvar $VARNAME_statsKeyedList statsList
    foreach k0 {sip} {
        foreach k1 [keylkeys statsList $k0] {
            puts "test"
        }
    }
}

and paste it into a vim buffer with filetype 'tcl', I get ...

proc dumpDut1Stats {VARNAME_statsKeyedList} {
        upvar $VARNAME_statsKeyedList statsList
            foreach k0 {sip} {
                        foreach k1 [keylkeys statsList $k0] {
                                        puts "test"
                                                }
                                                    }
                                                        }

I have been able to avoid the problem with this configuration...

  • Don't use 'indent' with the filetype command
  • Confirm indentexpr is unset
  • Disable autoindent and smartindent
  • Don't use 'a' and 'c' in formatoptions

[Note: using :set paste is impractical because it also disables the mapping I use for clipboard pasting]

While these steps seem to help me achieve the immediate goal of pasting code from clipboard to my vim buffer with correct indentation, it comes at a cost...

  • I do not benefit from the filetype's indentation script (i.e., files in the /usr/local/share/vim/vim82/indent directory)
  • I do not benefit from smartindent
  • I cannot enable certain formatoptions flags

Surely someone has a function to share that sets up the restrictive configuration, performs a clipboard paste, and returns the user's original configuration?

A secondary issue is that my formatoptions gets overwritten or modified by most of the filetype plugin scripts. This is because (apparently) my vimrc file is processed prior to the filetype plugin script.

Is there a way to automatically restore my formatoptions after the filetype plugin script is run?

BTW I'm using Ubuntu 20.04 with gvim 8.2. Also, in order to use Shift-Insert for pasting from my clipboard, I use these mappings...

nnoremap <S-Insert> "*p
inoremap <S-Insert> <C-R>*

and for completeness ...

:set all
--- Options ---
  aleph=224           cedit=^F          nodelcombine          foldlevelstart=-1   imstatusfunc=       matchtime=4         printdevice=        selectmode=       nosplitright          timeoutlen=1000   nowildmenu
noarabic              charconvert=        dictionary=         foldmethod=manual   imstyle=1           maxcombine=2        printencoding=      shell=/bin/bash     startofline         title               wildmode=full
  arabicshape       nocindent           nodiff                foldminlines=1      includeexpr=        maxfuncdepth=100    printfont=courier   shellcmdflag=-c     suffixesadd=        titlelen=85         wildoptions=
noallowrevins         cinoptions=         diffexpr=           foldnestmax=20      incsearch           maxmapdepth=1000    printmbcharset=     shellquote=         swapfile          nottimeout            winaltkeys=menu
  ambiwidth=single    cmdheight=1       nodigraph             formatexpr=         indentexpr=         maxmem=12182042     printmbfont=        shelltemp           swapsync=fsync      ttimeoutlen=-1      wincolor=
noautochdir           cmdwinheight=7      display=            formatprg=          infercase           menuitems=25        printoptions=       shellxquote=        switchbuf=          ttybuiltin          window=57
noautoindent          colorcolumn=        eadirection=both    fsync             noinsertmode          modeline            prompt              shellxescape=       synmaxcol=3000      ttyfast             winheight=1
noautoread            columns=235       noedcompatible      nogdefault            isprint=@,161-255 nomodelineexpr        pumheight=0       noshiftround          syntax=tcl          ttymouse=         nowinfixheight
noautowrite           comments=:#         emoji               guifontwide=        joinspaces          modelines=5         pumwidth=15         shiftwidth=4        tabline=            ttyscroll=999     nowinfixwidth
noautowriteall        commentstring=#%s   encoding=utf-8      guiheadroom=50      key=                modifiable          pythonthreehome=  noshortname           tabpagemax=10       undofile            winminheight=1
  background=dark   nocompatible          endofline           guipty              keymap=           nomodified            pythonhome=         showbreak=          tabstop=8           undolevels=1000     winminwidth=1
  backup              concealcursor=      equalalways         guitablabel=        keymodel=           more                pyxversion=0      noshowcmd             tagbsearch          undoreload=10000    winwidth=20
  backupcopy=auto     conceallevel=0      equalprg=           guitabtooltip=      keywordprg=man -s   mouse=a             quickfixtextfunc= noshowfulltag         tagcase=followic    updatecount=200   nowrap
  backupext=~         completefunc=     noerrorbells          helpheight=20       langmap=          nomousefocus          quoteescape=\       showmatch           tagfunc=            updatetime=4000     wrapmargin=0
  backupskip=/tmp/*   completepopup=      esckeys             helplang=en         langmenu=           mousehide         noreadonly            showmode            taglength=0         varsofttabstop=   nowrapscan
  balloondelay=600  noconfirm             eventignore=      nohidden            nolangnoremap         mousemodel=extend   redrawtime=2000     showtabline=1       tagrelative         vartabstop=         write
noballooneval       nocopyindent          expandtab           history=50          langremap           mousetime=500       regexpengine=0      sidescroll=8        tagstack            verbose=0         nowriteany
noballoonevalterm     cpoptions=aABceFs noexrc              nohkmap               laststatus=2      nonumber            norelativenumber      sidescrolloff=0     term=builtin_gui    verbosefile=        writebackup
  balloonexpr=        cscopepathcomp=0    fileencoding=     nohkmapp            nolazyredraw          numberwidth=4       remap               signcolumn=auto   notermbidi            viminfo='20,"80     writedelay=0
  belloff=            cscopeprg=cscope    fileformat=unix     hlsearch          nolinebreak           omnifunc=           report=2            smartcase         notermguicolors       viminfofile=
nobinary              cscopequickfix=   nofileignorecase      icon                lines=58            operatorfunc=     norevins            nosmartindent         termwinkey=         virtualedit=
nobomb              nocscoperelative      filetype=tcl        iconstring=         linespace=0       nopaste             norightleft         nosmarttab            termwinsize=        visualbell
nobreakindent       nocscopetag           fixendofline        ignorecase        nolisp                pastetoggle=        ruler               softtabstop=0     noterse               warn
  breakindentopt=     cscopetagorder=0    foldclose=          imactivatefunc=     list                patchexpr=          rulerformat=      nospell               textauto          noweirdinvert
  browsedir=last    nocscopeverbose       foldcolumn=0        imactivatekey=      loadplugins         patchmode=          scroll=28           spellfile=        notextmode            whichwrap=b,s
  bufhidden=        nocursorbind          foldenable        noimcmdline           magic             nopreserveindent    noscrollbind          spelllang=en        textwidth=512       wildchar=<Tab>
  buflisted         nocursorcolumn        foldexpr=0        noimdisable           makeef=             previewheight=12    scrolljump=1        spelloptions=       thesaurus=          wildcharm=0
  buftype=          nocursorline          foldignore=#        iminsert=0          makeencoding=       previewpopup=       scrolloff=0         spellsuggest=best notildeop             wildignore=
  cdpath=,,           debug=              foldlevel=0         imsearch=-1         makeprg=make      nopreviewwindow     nosecure            nosplitbelow          timeout           nowildignorecase
  backspace=start,eol,indent
  backupdir=~/.vim/bkupdir
  breakat= ^I!@*-+;:,./?
  casemap=internal,keepascii
  cinkeys=0{,0},0),0],:,0#,!^F,o,O,e
  cinwords=if,else,while,do,for,switch
  clipboard=autoselect,exclude:cons\|linux
  complete=.,w,b,u,t,i
  completeopt=menu,preview
  cryptmethod=blowfish2
  cursorlineopt=both
  define=^\s*#\s*define
  diffopt=internal,filler,closeoff
  directory=.,~/tmp,/var/tmp,/tmp
  errorfile=errors.err
  errorformat=%*[^"]"%f"%*\D%l: %m,"%f"%*\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\,,%-GIn file
 included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,"%f"\, line %l%*\D%c%*[^ ] %m,%D%*\a[%*\d]: Entering directory %*[`
']%f',%X%*\a[%*\d]: Leaving directory %*[`']%f',%D%*\a: Entering directory %*[`']%f',%X%*\a: Leaving directory %*[`']%f',%DMaking %*\a in %f,%f|%l| %m
  fileencodings=ucs-bom,utf-8,default,latin1
  fileformats=unix,dos
  fillchars=vert:|,fold:-
  foldmarker={{{,}}}
  foldopen=block,hor,mark,percent,quickfix,search,tag,undo
  foldtext=foldtext()
  formatoptions=tcroql
  formatlistpat=^\s*\d\+[\]:.)}\t ]\s*
  grepformat=%f:%l:%m,%f:%l%m,%f  %l%m
  grepprg=grep -n $* /dev/null
  guicursor=n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175
  guifont=Ubuntu Mono Bold 12
  guioptions=aegimrLtTl
  helpfile=/usr/local/share/vim/vim82/doc/help.txt
  highlight=8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:
VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLin
eSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC
  include=^\s*#\s*include
  indentkeys=0{,0},0),0],:,0#,!^F,o,O,e
  isfname=@,48-57,/,.,-,_,+,,,#,$,%,~,=
  isident=@,48-57,_,192-255
  iskeyword=@,48-57,_,192-255
  lispwords=defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,
dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-s
tream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-a
ccessors*,defclass,defmethod,print-unreadable-object
  listchars=precedes:<,extends:>
  matchpairs=(:),{:},[:]
  maxmempattern=1000
  maxmemtot=12182042
  mkspellmem=460000,2000,500
  mouseshape=i-r:beam,s:updown,sd:udsizing,vs:leftright,vd:lrsizing,m:no,ml:up-arrow,v:rightup-arrow
  nrformats=bin,octal,hex
  packpath=~/.vim,/usr/local/share/vim/vimfiles,/usr/local/share/vim/vim82,/usr/local/share/vim/vimfiles/after,~/.vim/after
  paragraphs=IPLPPPQPP TPHPLIPpLpItpplpipbp
  path=.,/usr/include,,
  perldll=libperl.so.5.30
  printexpr=system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error
  printheader=%<%f%h%m%=Page %N
  pythonthreedll=libpython3.8.so.1.0
  pythondll=libpython2.7.so.1.0
  rightleftcmd=search
  rubydll=libruby-2.7.so.2.7
  runtimepath=~/.vim,/usr/local/share/vim/vimfiles,/usr/local/share/vim/vim82,/usr/local/share/vim/vimfiles/after,~/.vim/after
  scrollopt=ver,jump
  sections=SHNHH HUnhsh
  selection=inclusive
  sessionoptions=blank,buffers,curdir,folds,help,options,tabpages,winsize,terminal
  shellpipe=2>&1| tee
  shellredir=>%s 2>&1
  shortmess=filnxtToOS
  spellcapcheck=[.?!]\_[\])'"^I ]\+
  statusline= %<%F [%M%R%H%W%Y,%{&ff}]  %= line:%l/%L col:%c   %p%%
  suffixes=.bak,~,.o,.h,.info,.swp,.obj
  tags=./tags,./TAGS,tags,TAGS
  termencoding=utf-8
  termwinscroll=10000
  titleold=RmbInspiro2018
  titlestring=[ %t ] VIM
  toolbar=icons,tooltips
  toolbariconsize=small
  ttytype=builtin_gui
  undodir=~/.vim/undodir
  viewdir=~/.vim/view
  viewoptions=folds,options,cursor,curdir


  • Do you speak about insert mode pasting? like <C-r>*? Because I can't see the issue with normal mode "*p. – Maxim Kim Oct 17 '20 at 8:57
  • Yes, this is an issue with insert mode pasting, not normal mode. – Paperclip Bob Oct 17 '20 at 12:41
  • It’s possible there’s a better dupe-target, but this was the first one I found. – D. Ben Knoble Oct 17 '20 at 13:29
  • I don't see this as a dupe since I am specifically asking for a solution that does not involve paste/nopaste (from my orig q: "Note: using :set paste is impractical because it also disables the mapping I use for clipboard pasting"). Also @MaximKim provides a very good solution here which is not found in the dupe-target's answers. – Paperclip Bob Oct 18 '20 at 1:37
1

When you paste something in insert mode, paste option makes a huge difference.

And if you don't want to toggle it then try using normal mode pasting invoked from insert mode mapping.

This is the naive attempt to solve your pasting issue:

inoremap <S-Insert> <ESC>"*p`]a
  1. go to normal mode with <ESC>
  2. paste from * register with "*p
  3. goto the last character of the previously changed text with `]
  4. start insert mode after current char with a

You might want to enhance it though -- there are edge cases it doesn't handle (cursor position after paste is incorrect if pasted from beginning of the line, for example).

UPD

a better version would be:

inoremap <expr> <S-Insert> printf('<ESC>"*%s`]a', col('.') == 1 ? 'P' : 'p')

It is basically the same version as above, but with check if a cursor is on first column or not. Depending on that P or p is used to paste.

  • It previously occurred to me to try something like your approach (escape to normal mode, perform the paste, return to insert mode), but it seemed a bit crude. In retrospect your suggestion is a hell of a lot less crude than the alternatives I have been trying out! Your revised version is working well for me :-) – Paperclip Bob Oct 17 '20 at 12:44

Not the answer you're looking for? Browse other questions tagged or ask your own question.