@@ -14,44 +14,51 @@ 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" )
17
+ function ls_style_to_octal (rwx_string )
18
+ local result = 0
19
+ local value = 0
20
+
21
+ for i = 1 , # rwx_string , 3 do
22
+ local chunk = rwx_string :sub (i , i + 2 )
23
+ value = 0
24
+
25
+ if chunk :sub (1 , 1 ) == ' r' then value = value + 4 end
26
+ if chunk :sub (2 , 2 ) == ' w' then value = value + 2 end
27
+ if chunk :sub (3 , 3 ) == ' x' then value = value + 1 end
28
+
29
+ result = result * 8 + value
30
+ utils .echo_info ((" ls style mode: %o" ):format (result ))
50
31
end
51
-
32
+
52
33
return result
53
34
end
54
35
36
+
37
+ function chmod_style_to_octal (chmod_string )
38
+ local owner , group , other = 0 , 0 , 0
39
+
40
+ for part in chmod_string :gmatch (' [^,]+' ) do
41
+ utils .echo_info ((' part: %s' ):format (part ))
42
+ local who , what = part :match (' (%a+)[=+](.+)' )
43
+ utils .echo_info ((' who: %s what: %s' ):format (who , what ))
44
+ if not who or not what then
45
+ return nil
46
+ end
47
+
48
+
49
+ local perm = 0
50
+ if what :find (' r' ) then perm = perm + 4 end
51
+ if what :find (' w' ) then perm = perm + 2 end
52
+ if what :find (' x' ) then perm = perm + 1 end
53
+
54
+ if who :find (' u' ) or who :find (' a' ) then owner = bit .bor (owner , perm ) end
55
+ if who :find (' g' ) or who :find (' a' ) then group = bit .bor (group , perm ) end
56
+ if who :find (' o' ) or who :find (' a' ) then other = bit .bor (other , perm ) end
57
+ end
58
+
59
+ return owner * 64 + group * 8 + other
60
+ end
61
+
55
62
function Tangle :tangle ()
56
63
local block_content_by_name = {}
57
64
--- @type OrgBlockTangleInfo[]
@@ -127,17 +134,28 @@ function Tangle:tangle()
127
134
128
135
local promises = {}
129
136
for filename , block in pairs (tangle_info ) do
130
- local mode_str = block [' mode' ]
131
- if mode_str and mode_str :sub (1 , 1 ) == ' o' then
132
- mode_str [1 ] = 0
133
- mode_str = mode_to_string (mode_str )
134
- end
135
137
136
138
table.insert (
137
139
promises ,
138
- utils .writefile (filename , table.concat (self :_remove_obsolete_indent (block [' content' ]), ' \n ' ), mode_str )
140
+ utils .writefile (filename , table.concat (self :_remove_obsolete_indent (block [' content' ]), ' \n ' ))
139
141
)
140
142
143
+ local mode_str = block [' mode' ]
144
+ local mode = nil
145
+
146
+ if mode_str and mode_str :sub (1 , 1 ) == ' o' then
147
+ mode = tonumber (mode_str :sub (2 ), 8 )
148
+ else
149
+ mode = chmod_style_to_octal (mode_str )
150
+ if mode == nil then
151
+ mode = ls_style_to_octal (mode_str )
152
+ end
153
+ end
154
+
155
+ if mode then
156
+ utils .echo_info ((' change mode %s mode %o' ):format (filename , mode ))
157
+ vim .loop .fs_chmod (filename , mode )
158
+ end
141
159
end
142
160
Promise .all (promises ):wait ()
143
161
utils .echo_info ((' Tangled %d blocks from %s' ):format (# valid_blocks , vim .fn .fnamemodify (self .file .filename , ' :t' )))
0 commit comments