Vim Tips Wiki
(Highlighting of the patch)
No edit summary
Tag: sourceedit
 
(7 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{ScriptComments|231|Smart Tabs: use tabs for indent, spaces for alignment}}
+
{{ScriptComments|Smart Tabs: use tabs for indent, spaces for alignment}}
  +
  +
== Adopted to github ==
  +
  +
As it seems original author is not actively taking care of it, I've moved this script to github:
  +
https://github.com/dpc/vim-smarttabs
  +
  +
  +
==Bug report (version 2.6) ==
  +
THere is a bug in version 2.6 that prevents ranged '=' command
  +
from working. It displays an error message about missing 'b:ctab_lastalign'.
  +
Here is the fix:
  +
<source lang="diff">--- ctab.vim>---2012-05-04 20:19:47.143269297 +0400
  +
+++ /smbexport/ctab.vim>2012-05-04 20:10:17.590011955 +0400
  +
@@ -221,7 +221,9 @@
  +
if a:line == line('.')
  +
let b:ctab_lastalign=a:line
  +
else
  +
- unlet b:ctab_lastalign
  +
+ if exists('b:ctab_lastalign')
  +
+ unlet b:ctab_lastalign
  +
+ endif
  +
endif
  +
set ts=50
  +
set sw=50</source>
   
 
==Bug report==
 
==Bug report==
Line 20: Line 44:
   
 
--[[User:Themiwi|Themiwi]] 14:51, August 21, 2010 (UTC)
 
--[[User:Themiwi|Themiwi]] 14:51, August 21, 2010 (UTC)
  +
  +
==Bug with empty lines==
  +
I found problem in ctab.vim script.
  +
  +
How to reproduce:
  +
[[File:Ctab_problem.png|thumb|center|254px|
  +
<source lang="vim">
  +
:e test.c
  +
:set cindent
  +
i
  +
test() {<CR>
  +
<CR>
  +
<CR>
  +
test();<CR>
  +
<CR>
  +
}<CR>
  +
</source>]]
  +
  +
I fixed the problem and add some minor fixes (correct undo for some <CR>, handling <Esc>):
  +
<source lang="diff">
  +
--- ctab.vim.orig 2011-02-07 11:46:44.000000000 +0300
  +
+++ ctab.vim 2011-02-07 13:35:50.000000000 +0300
  +
@@ -199,6 +199,9 @@
  +
" Check the alignment of line.
  +
" Used in the case where some alignment whitespace is required .. like for unmatched brackets.
  +
fun! s:CheckAlign(line)
  +
+ if getline(line('.') - 1) =~ '^\s*$'
  +
+ call setline(line('.') - 1, '')
  +
+ endif
  +
if &expandtab || !(&autoindent || &indentexpr || &cindent)
  +
return ''
  +
endif
  +
@@ -246,13 +249,27 @@
  +
fun! s:CheckCR()
  +
echo 'SID:'.s:SID()
  +
if getline('.') =~ '^\s*$'
  +
- return "\<CR>"
  +
+ return "\<c-r>=<SNR>".s:SID().'_RemoveSpaces(line(''.''))'."\<CR>\<CR>\<END>"
  +
else
  +
return "\<CR>\<c-r>=<SNR>".s:SID().'_CheckAlign(line(''.''))'."\<CR>\<END>"
  +
endif
  +
endfun
  +
  +
+ fun! s:RemoveSpaces(lnum)
  +
+ undojoin
  +
+ call setline(a:lnum, '')
  +
+ return ''
  +
+ endfun
  +
+
  +
+ fun! s:CheckEsc()
  +
+ if getline('.') =~ '^\s*$'
  +
+ return "\<c-r>=<SNR>".s:SID().'_RemoveSpaces(line(''.''))'."\<CR>\<Esc>\<END>"
  +
+ endif
  +
+ return "\<Esc>"
  +
+ endfun
  +
+
  +
"exe 'inoremap '.s:buff_map.'<silent> <CR> <CR><c-r>=<SID>CheckAlign(line(''.''))."\<lt>END>"<CR>'
  +
+ exe 'inoremap '.s:buff_map.'<silent> <expr> <Esc> <SID>CheckEsc()'
  +
exe 'inoremap '.s:buff_map.'<silent> <expr> <CR> <SID>CheckCR()'
  +
exe 'nnoremap '.s:buff_map.'<silent> o o<c-r>=<SID>CheckAlign(line(''.''))."\<lt>END>"<CR>'
  +
exe 'nnoremap '.s:buff_map.'<silent> O O<c-r>=<SID>CheckAlign(line(''.''))."\<lt>END>"<CR>'
  +
</source>
  +
--[[User:Konstantin.lepa|Konstantin Lepa]] 11:05, February 7, 2011 (UTC)
  +
  +
==Inserting carriage return jumps to end of line==
  +
I'm experiencing a bug with ctab.vim verison 2.6 in which typing a carriage return in the middle of a line while in insert mode will place your cursor at the end of the new line. The expected behaviour is that the cursor will stay in front of the text that the carriage return was inserted before.
  +
  +
The reason this happens is because it expects that there is no text after the carriage return and tries to jump to after the inserted spaces/tabs. It does this simply with the <code>&lt;END&gt;</code> key.
  +
  +
I'm not particularly experienced with writing vim scripts, so I don't have a fix. I can't find a way to move to the first non-whitespace character without leaving insert mode. Leaving insert mode would clear the new line if you're inserting the carriage return at the end of a line.
  +
[[User:Sftrabbit|Sftrabbit]] ([[User talk:Sftrabbit|talk]]) 15:58, October 3, 2013 (UTC)
  +
  +
----
  +
  +
Hi Sftrabbit. I was also annoyed by this.
  +
I think it suffices to simply get rid of the <code>\&lt;END&gt;</code> character.
  +
  +
The line, for me, now reads:
  +
  +
<code>return "\<CR>\<c-r>=<SNR>".s:SID().'_CheckAlign(line(''.''))'."\<CR>"</code>
   
 
==Comments==
 
==Comments==

Latest revision as of 22:25, 2 September 2015

Use this page to discuss script 231 Smart Tabs: use tabs for indent, spaces for alignment

  • Add constructive comments, bug reports, or discuss improvements (see the guideline).
  • Do not document the script here (the author should do that on vim.org).
  • This page may be out of date: check the script's vim.org page above, and its release notes.

Adopted to github[]

As it seems original author is not actively taking care of it, I've moved this script to github: https://github.com/dpc/vim-smarttabs


Bug report (version 2.6)[]

THere is a bug in version 2.6 that prevents ranged '=' command from working. It displays an error message about missing 'b:ctab_lastalign'. Here is the fix:

--- ctab.vim>---2012-05-04 20:19:47.143269297 +0400
+++ /smbexport/ctab.vim>2012-05-04 20:10:17.590011955 +0400
@@ -221,7 +221,9 @@
       if a:line == line('.')
         let b:ctab_lastalign=a:line
       else
-        unlet b:ctab_lastalign
+        if exists('b:ctab_lastalign')
+          unlet b:ctab_lastalign
+        endif
       endif
       set ts=50
       set sw=50

Bug report[]

There is a bug on line 284 of ctab.vim, version 2.3 which prevents :RetabIndent from working. Below patch fixes this:

diff -- a/plugin/ctab.vim b/plugin/ctab.vim
index 98d305b..9e873fe 100644
--- a/plugin/ctab.vim
+++ b/plugin/ctab.vim
@@ -281,7 +281,7 @@ fun! s:RetabIndent( bang, firstl, lastl, tab )
   let checkspace=((!&expandtab)? "^\<tab>* ": "^ *\<tab>")
   let l = a:firstl
   let force= a:tab != '' && a:tab != 0 && (a:tab != &tabstop)
-  let checkalign = &expandtab || !(&autoindent || &indentexpr || &cindent) ! exists('g:ctab_disable_checkalign') || g:ctab_disable_checkalign==0
+  let checkalign = &expandtab || !(&autoindent || &indentexpr || &cindent) || ! exists('g:ctab_disable_checkalign') || g:ctab_disable_checkalign==0
   let newtabstop = (force?(a:tab):(&tabstop))
   while l <= a:lastl
     let txt=getline(l)

--Themiwi 14:51, August 21, 2010 (UTC)

Bug with empty lines[]

I found problem in ctab.vim script.

How to reproduce:

Ctab problem

:e test.c
:set cindent
i
test() {<CR>
<CR>
<CR>
test();<CR>
<CR>
}<CR>

I fixed the problem and add some minor fixes (correct undo for some <CR>, handling <Esc>):

--- ctab.vim.orig	2011-02-07 11:46:44.000000000 +0300
+++ ctab.vim	2011-02-07 13:35:50.000000000 +0300
@@ -199,6 +199,9 @@
   " Check the alignment of line.
   " Used in the case where some alignment whitespace is required .. like for unmatched brackets.
   fun! s:CheckAlign(line)
+    if getline(line('.') - 1) =~ '^\s*$'
+      call setline(line('.') - 1, '')
+    endif
     if &expandtab || !(&autoindent || &indentexpr || &cindent)
       return ''
     endif
@@ -246,13 +249,27 @@
   fun! s:CheckCR()
     echo 'SID:'.s:SID()
     if getline('.') =~ '^\s*$'
-      return "\<CR>"
+      return "\<c-r>=<SNR>".s:SID().'_RemoveSpaces(line(''.''))'."\<CR>\<CR>\<END>"
     else
       return "\<CR>\<c-r>=<SNR>".s:SID().'_CheckAlign(line(''.''))'."\<CR>\<END>"
     endif
   endfun
 
+  fun! s:RemoveSpaces(lnum)
+    undojoin
+    call setline(a:lnum, '')
+    return ''
+  endfun
+
+  fun! s:CheckEsc()
+    if getline('.') =~ '^\s*$'
+      return "\<c-r>=<SNR>".s:SID().'_RemoveSpaces(line(''.''))'."\<CR>\<Esc>\<END>"
+    endif
+    return "\<Esc>"
+  endfun
+
   "exe 'inoremap '.s:buff_map.'<silent> <CR> <CR><c-r>=<SID>CheckAlign(line(''.''))."\<lt>END>"<CR>'
+  exe 'inoremap '.s:buff_map.'<silent> <expr> <Esc> <SID>CheckEsc()'
   exe 'inoremap '.s:buff_map.'<silent> <expr> <CR> <SID>CheckCR()'
   exe 'nnoremap '.s:buff_map.'<silent> o o<c-r>=<SID>CheckAlign(line(''.''))."\<lt>END>"<CR>'
   exe 'nnoremap '.s:buff_map.'<silent> O O<c-r>=<SID>CheckAlign(line(''.''))."\<lt>END>"<CR>'

--Konstantin Lepa 11:05, February 7, 2011 (UTC)

Inserting carriage return jumps to end of line[]

I'm experiencing a bug with ctab.vim verison 2.6 in which typing a carriage return in the middle of a line while in insert mode will place your cursor at the end of the new line. The expected behaviour is that the cursor will stay in front of the text that the carriage return was inserted before.

The reason this happens is because it expects that there is no text after the carriage return and tries to jump to after the inserted spaces/tabs. It does this simply with the <END> key.

I'm not particularly experienced with writing vim scripts, so I don't have a fix. I can't find a way to move to the first non-whitespace character without leaving insert mode. Leaving insert mode would clear the new line if you're inserting the carriage return at the end of a line. Sftrabbit (talk) 15:58, October 3, 2013 (UTC)


Hi Sftrabbit. I was also annoyed by this. I think it suffices to simply get rid of the \<END> character.

The line, for me, now reads:

return "\<CR>\<c-r>=<SNR>".s:SID().'_CheckAlign(line(.))'."\<CR>"

Comments[]

Some information on this plugin is at Indent with tabs, align with spaces. JohnBeckett 09:45, August 22, 2010 (UTC)