aboutsummaryrefslogtreecommitdiff
path: root/autoload/big_file_options.vim
blob: 023c6726e956e29a63b1369333ceb0b6d74042ad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
" If we can use filesize to detect the big file early, we should
function! big_file_options#CheckPre(filename) abort

  " Try and get filesize, bail out if we can't
  let size = getfsize(a:filename)
  if size == -1
    return
  endif

  " Set the buffer's big flag to whether the file is verifiably outsize
  let b:big_file_options_big = size == -2 || size > s:Limit()

  " If we found it's a big file, call the early options set
  if b:big_file_options_big
    call s:SetPre()
  endif

endfunction

" If it's still indeterminate (stdin read?), try to check the buffer size
" itself
function! big_file_options#CheckPost() abort

  " The BufReadPre hook couldn't tell how big the file was; we'll examine it
  " now it's loaded into the buffer instead
  if !exists('b:big_file_options_big')

    " Test buffer size, bail if that doesn't work either
    let size = line2byte(line('$') + 1)
    if size == -1
      return
    endif

    " Flag the buffer's oversize status, if it's positive, we'll catch up and
    " run the early options set now
    let b:big_file_options_big = size > s:Limit()
    if b:big_file_options_big
      call s:SetPre()
    endif

  endif

  " If the buffer size is verifiably over the threshold, run the late options
  " set
  if b:big_file_options_big
    call s:SetPost()
  endif

endfunction

" Wrapper function to get the configured size limit, default to 10 MiB
function! s:Limit() abort
  let limit = get(g:, 'big_file_options_limit', 10 * 1024 * 1024)
  return limit
endfunction

" These options can and should be set as early as possible
function! s:SetPre() abort

  " These are always set
  setlocal noswapfile
  setlocal undolevels=-1
  if has('persistent_undo')
    setlocal noundofile
  endif

  " Decide whether to set readonly options
  let readonly = get(g:, 'big_file_options_readonly', 1)
  if readonly
    setlocal buftype=nowrite
    setlocal nomodifiable
    setlocal readonly
  endif
endfunction

" These options need to be set later, after the buffer has loaded
function! s:SetPost() abort

  " Force filetype off
  setlocal filetype=NONE

  " Syntax features
  if has('syntax')

    " Disable syntax highlighting if configured
    let syntax = get(g:, 'big_file_options_syntax', 0)
    if !syntax
      setlocal syntax=OFF
    endif

    " Force maximum syntax columns down if configured
    if exists('+synmaxcol')
      let synmaxcol = get(g:, 'big_file_options_synmaxcol', 256)
      if &synmaxcol > synmaxcol
        let &l:synmaxcol = synmaxcol
      endif
    endif

  endif

  " Tell the user what we've done
  echomsg 'Big file detected, set appropriate options'

endfunction

" If we can use filesize to detect the big file early, we should
function! big_file_options#CheckPre(filename) abort

  " Try and get filesize, bail out if we can't
  let size = getfsize(a:filename)
  if size == -1
    return
  endif

  " Set the buffer's big flag to whether the file is verifiably outsize
  let b:big_file_options_big = size == -2 || size > s:Limit()

  " If we found it's a big file, call the early options set
  if b:big_file_options_big
    call s:SetPre()
  endif

endfunction

" If it's still indeterminate (stdin read?), try to check the buffer size
" itself
function! big_file_options#CheckPost() abort

  " The BufReadPre hook couldn't tell how big the file was; we'll examine it
  " now it's loaded into the buffer instead
  if !exists('b:big_file_options_big')

    " Test buffer size, bail if that doesn't work either
    let size = line2byte(line('$') + 1)
    if size == -1
      return
    endif

    " Flag the buffer's oversize status, if it's positive, we'll catch up and
    " run the early options set now
    let b:big_file_options_big = size > s:Limit()
    if b:big_file_options_big
      call s:SetPre()
    endif

  endif

  " If the buffer size is verifiably over the threshold, run the late options
  " set
  if b:big_file_options_big
    call s:SetPost()
  endif

endfunction