@@ -7,8 +7,8 @@ using Base: shell_split, shell_escape, find_source_file
7
7
"""
8
8
EDITOR_CALLBACKS :: Vector{Function}
9
9
10
- A vector of editor callback functions, which take as arguments `cmd`, `path` and
11
- `line ` and which is then expected to either open an editor and return `true` to
10
+ A vector of editor callback functions, which take as arguments `cmd`, `path`, `line`
11
+ and `column ` and which is then expected to either open an editor and return `true` to
12
12
indicate that it has handled the request, or return `false` to decline the
13
13
editing request.
14
14
"""
@@ -21,19 +21,20 @@ Define a new editor matching `pattern` that can be used to open a file (possibly
21
21
at a given line number) using `fn`.
22
22
23
23
The `fn` argument is a function that determines how to open a file with the
24
- given editor. It should take three arguments, as follows:
24
+ given editor. It should take four arguments, as follows:
25
25
26
26
* `cmd` - a base command object for the editor
27
27
* `path` - the path to the source file to open
28
28
* `line` - the line number to open the editor at
29
+ * `column` - the column number to open the editor at
29
30
30
- Editors which cannot open to a specific line with a command may ignore the
31
- `line` argument. The `fn` callback must return either an appropriate `Cmd`
32
- object to open a file or `nothing` to indicate that they cannot edit this file.
33
- Use `nothing` to indicate that this editor is not appropriate for the current
34
- environment and another editor should be attempted. It is possible to add more
35
- general editing hooks that need not spawn external commands by pushing a
36
- callback directly to the vector `EDITOR_CALLBACKS`.
31
+ Editors which cannot open to a specific line with a command or a specific column
32
+ may ignore the `line` and/or `column` argument. The `fn` callback must return
33
+ either an appropriate `Cmd` object to open a file or `nothing` to indicate that
34
+ they cannot edit this file. Use `nothing` to indicate that this editor is not
35
+ appropriate for the current environment and another editor should be attempted.
36
+ It is possible to add more general editing hooks that need not spawn
37
+ external commands by pushing a callback directly to the vector `EDITOR_CALLBACKS`.
37
38
38
39
The `pattern` argument is a string, regular expression, or an array of strings
39
40
and regular expressions. For the `fn` to be called, one of the patterns must
@@ -52,7 +53,7 @@ set `wait=true` and julia will wait for the editor to close before resuming.
52
53
If one of the editor environment variables is set, but no editor entry matches it,
53
54
the default editor entry is invoked:
54
55
55
- (cmd, path, line) -> `\$ cmd \$ path`
56
+ (cmd, path, line, column ) -> `\$ cmd \$ path`
56
57
57
58
Note that many editors are already defined. All of the following commands should
58
59
already work:
@@ -88,9 +89,14 @@ The following defines the usage of terminal-based `emacs`:
88
89
`define_editor` was introduced in Julia 1.4.
89
90
"""
90
91
function define_editor (fn:: Function , pattern; wait:: Bool = false )
91
- callback = function (cmd:: Cmd , path:: AbstractString , line:: Integer )
92
+ callback = function (cmd:: Cmd , path:: AbstractString , line:: Integer , column :: Integer )
92
93
editor_matches (pattern, cmd) || return false
93
- editor = fn (cmd, path, line)
94
+ editor = if ! applicable (fn, cmd, path, line, column)
95
+ # Be backwards compatible with editors that did not define the newly added column argument
96
+ fn (cmd, path, line)
97
+ else
98
+ fn (cmd, path, line, column)
99
+ end
94
100
if editor isa Cmd
95
101
if wait
96
102
run (editor) # blocks while editor runs
@@ -113,35 +119,50 @@ editor_matches(ps::AbstractArray, cmd::Cmd) = any(editor_matches(p, cmd) for p i
113
119
114
120
function define_default_editors ()
115
121
# fallback: just call the editor with the path as argument
116
- define_editor (r" .*" ) do cmd, path, line
122
+ define_editor (r" .*" ) do cmd, path, line, column
117
123
` $cmd $path `
118
124
end
119
- define_editor (Any[r" \b emacs" , " gedit" , r" \b gvim" ]) do cmd, path, line
120
- ` $cmd +$line $path `
125
+ # vim family
126
+ for (editors, wait) in [[Any[" vim" , " vi" , " nvim" , " mvim" ], true ],
127
+ [Any[" \b gvim" ], false ]]
128
+ define_editor (editors; wait) do cmd, path, line, column
129
+ cmd = line == 0 ? ` $cmd $path ` :
130
+ column == 0 ? ` $cmd +$line $path ` :
131
+ ` $cmd "+normal $(line) G$(column) |" $path `
132
+ end
133
+ end
134
+ define_editor (" nano" ; wait= true ) do cmd, path, line, column
135
+ cmd = ` $cmd +$line ,$column $path `
121
136
end
122
- # Must check that emacs not running in -t/-nw before regex match for general emacs
123
- define_editor (Any[
124
- " vim" , " vi" , " nvim" , " mvim" , " nano" , " micro" , " kak" ,
125
- r" \b emacs\b .*\s (-nw|--no-window-system)\b " ,
126
- r" \b emacsclient\b .\s *-(-?nw|t|-?tty)\b " ,
127
- ], wait= true ) do cmd, path, line
137
+ # emacs (must check that emacs not running in -t/-nw before regex match for general emacs)
138
+ for (editors, wait) in [[Any[r" \b emacs" ], false ],
139
+ [Any[r" \b emacs\b .*\s (-nw|--no-window-system)\b " , r" \b emacsclient\b .\s *-(-?nw|t|-?tty)\b " ], true ]]
140
+ define_editor (editors; wait) do cmd, path, line, column
141
+ ` $cmd +$line :$column $path `
142
+ end
143
+ end
144
+ # Other editors
145
+ define_editor (" gedit" ) do cmd, path, line, column
146
+ ` $cmd +$line :$column $path `
147
+ end
148
+ define_editor (Any[" micro" , " kak" ]; wait= true ) do cmd, path, line, column
128
149
` $cmd +$line $path `
129
150
end
130
- define_editor ([" textmate" , " mate" , " kate" ]) do cmd, path, line
151
+ define_editor ([" textmate" , " mate" , " kate" ]) do cmd, path, line, column
131
152
` $cmd $path -l $line `
132
153
end
133
- define_editor (Any[r" \b subl" , r" \b atom" , " pycharm" , " bbedit" ]) do cmd, path, line
154
+ define_editor (Any[r" \b subl" , r" \b atom" , " pycharm" , " bbedit" ]) do cmd, path, line, column
134
155
` $cmd $path :$line `
135
156
end
136
- define_editor ([" code" , " code-insiders" ]) do cmd, path, line
137
- ` $cmd -g $path :$line `
157
+ define_editor ([" code" , " code-insiders" ]) do cmd, path, line, column
158
+ ` $cmd -g $path :$line : $column `
138
159
end
139
- define_editor (r" \b notepad++" ) do cmd, path, line
160
+ define_editor (r" \b notepad++" ) do cmd, path, line, column
140
161
` $cmd $path -n$line `
141
162
end
142
163
if Sys. iswindows ()
143
- define_editor (r" \b CODE\. EXE\b " i ) do cmd, path, line
144
- ` $cmd -g $path :$line `
164
+ define_editor (r" \b CODE\. EXE\b " i ) do cmd, path, line, column
165
+ ` $cmd -g $path :$line : $column `
145
166
end
146
167
callback = function (cmd:: Cmd , path:: AbstractString , line:: Integer )
147
168
cmd == ` open` || return false
@@ -157,7 +178,7 @@ function define_default_editors()
157
178
end
158
179
pushfirst! (EDITOR_CALLBACKS, callback)
159
180
elseif Sys. isapple ()
160
- define_editor (" open" ) do cmd, path, line
181
+ define_editor (" open" ) do cmd, path, line, column
161
182
` open -t $path `
162
183
end
163
184
end
@@ -186,23 +207,27 @@ function editor()
186
207
end
187
208
188
209
"""
189
- edit(path::AbstractString, line::Integer=0)
210
+ edit(path::AbstractString, line::Integer=0, column::Integer=0 )
190
211
191
212
Edit a file or directory optionally providing a line number to edit the file at.
192
213
Return to the `julia` prompt when you quit the editor. The editor can be changed
193
214
by setting `JULIA_EDITOR`, `VISUAL` or `EDITOR` as an environment variable.
194
215
195
216
See also [`define_editor`](@ref).
196
217
"""
197
- function edit (path:: AbstractString , line:: Integer = 0 )
218
+ function edit (path:: AbstractString , line:: Integer = 0 , column :: Integer = 0 )
198
219
path isa String || (path = convert (String, path))
199
220
if endswith (path, " .jl" )
200
221
p = find_source_file (path)
201
222
p != = nothing && (path = p)
202
223
end
203
224
cmd = editor ()
204
225
for callback in EDITOR_CALLBACKS
205
- callback (cmd, path, line) && return
226
+ if ! applicable (callback, cmd, path, line, column)
227
+ callback (cmd, path, line) && return
228
+ else
229
+ callback (cmd, path, line, column) && return
230
+ end
206
231
end
207
232
# shouldn't happen unless someone has removed fallback entry
208
233
error (" no editor found" )
0 commit comments