@@ -14,6 +14,44 @@ function Tangle:new(opts)
14
14
}, self )
15
15
end
16
16
17
+ function mode_to_string (mode )
18
+ local permissions = {" ---" , " --x" , " -w-" , " -wx" , " r--" , " r-x" , " rw-" , " rwx" }
19
+ local result = " "
20
+
21
+ -- File type
22
+ local file_type = bit .band (bit .rshift (mode , 12 ), 15 )
23
+ local type_char = {
24
+ [0 ] = " -" , -- regular file
25
+ [1 ] = " p" , -- named pipe (fifo)
26
+ [2 ] = " c" , -- character special
27
+ [4 ] = " d" , -- directory
28
+ [6 ] = " b" , -- block special
29
+ [8 ] = " f" , -- regular file (rarely used)
30
+ [10 ] = " l" , -- symbolic link
31
+ [12 ] = " s" -- socket
32
+ }
33
+ result = result .. (type_char [file_type ] or " -" )
34
+
35
+ -- Owner, group, others permissions
36
+ for i = 2 , 0 , - 1 do
37
+ local perm = bit .band (bit .rshift (mode , i * 3 ), 7 )
38
+ result = result .. permissions [perm + 1 ]
39
+ end
40
+
41
+ -- Special bits
42
+ if bit .band (mode , 0x800 ) ~= 0 then -- sticky bit
43
+ result = result :sub (1 , 9 ) .. (result :sub (10 , 10 ) == " -" and " T" or " t" )
44
+ end
45
+ if bit .band (mode , 0x400 ) ~= 0 then -- setgid
46
+ result = result :sub (1 , 6 ) .. (result :sub (7 , 7 ) == " -" and " S" or " s" )
47
+ end
48
+ if bit .band (mode , 0x200 ) ~= 0 then -- setuid
49
+ result = result :sub (1 , 3 ) .. (result :sub (4 , 4 ) == " -" and " S" or " s" )
50
+ end
51
+
52
+ return result
53
+ end
54
+
17
55
function Tangle :tangle ()
18
56
local block_content_by_name = {}
19
57
--- @type OrgBlockTangleInfo[]
@@ -95,17 +133,17 @@ function Tangle:tangle()
95
133
96
134
local promises = {}
97
135
for filename , block in pairs (tangle_info ) do
136
+ local mode_str = block [' mode' ]
137
+ if mode_str and mode_str :sub (1 , 1 ) == ' o' then
138
+ mode_str [1 ] = 0
139
+ mode_str = mode_to_string (mode_str )
140
+ end
141
+
98
142
table.insert (
99
143
promises ,
100
- utils .writefile (filename , table.concat (self :_remove_obsolete_indent (block [' content' ]), ' \n ' ))
144
+ utils .writefile (filename , table.concat (self :_remove_obsolete_indent (block [' content' ]), ' \n ' ), mode_str )
101
145
)
102
146
103
- local mode_str = block [' mode' ]
104
- if mode_str and mode_str :sub (1 , 1 ) == ' o' then
105
- mode_str = mode_str :sub (2 )
106
- local mode_num = tonumber (mode_str , 8 )
107
- vim .loop .fs_chmod (filename , mode_num )
108
- end
109
147
end
110
148
Promise .all (promises ):wait ()
111
149
utils .echo_info ((' Tangled %d blocks from %s' ):format (# valid_blocks , vim .fn .fnamemodify (self .file .filename , ' :t' )))
0 commit comments