@@ -14,6 +14,44 @@ function Tangle:new(opts)
1414 }, self )
1515end
1616
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+
1755function Tangle :tangle ()
1856 local block_content_by_name = {}
1957 --- @type OrgBlockTangleInfo[]
@@ -95,17 +133,17 @@ function Tangle:tangle()
95133
96134 local promises = {}
97135 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+
98142 table.insert (
99143 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 )
101145 )
102146
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
109147 end
110148 Promise .all (promises ):wait ()
111149 utils .echo_info ((' Tangled %d blocks from %s' ):format (# valid_blocks , vim .fn .fnamemodify (self .file .filename , ' :t' )))
0 commit comments