From fff94a36a5b83e5b07a170bd7ac8f17406cfb8fb Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Sat, 19 Nov 2022 17:50:34 +0000 Subject: [PATCH] Add option to visit the end of a file. * lisp/startup.el (command-line-1): Count from the end of the file when the line number is negative. * lisp/server.el (server-process-filter): Allow negative line numbers. (server-goto-line-column): Count from the end of the file when the line number is negative. * src/emacs.c (usage_message): Mention the optional '-'. * lib-src/emacsclient.c (main): Allow negative line numbers. (print_help_and_exit): Mention the optional '-'. * doc/emacs/cmdargs.texi (Action Arguments): * doc/emacs/misc.texi (emacsclient Options): * doc/man/emacs.1.in: * doc/man/emacsclient.1: Document negative line numbers. --- doc/emacs/cmdargs.texi | 9 +++++++++ doc/emacs/misc.texi | 8 +++++--- doc/man/emacs.1.in | 8 ++++++-- doc/man/emacsclient.1 | 7 ++++--- lib-src/emacsclient.c | 3 ++- lisp/server.el | 11 ++++++++--- lisp/startup.el | 15 ++++++++++----- src/emacs.c | 4 ++-- 8 files changed, 46 insertions(+), 19 deletions(-) diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index 0f7acd8797..4a7484860a 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi @@ -119,6 +119,15 @@ Action Arguments Visit the specified @var{file}, then go to line number @var{linenum} and put point at column number @var{columnnum}. +@item +-@var{linenum} @var{file} +Visit the specified @var{file}, then go to line number @var{linenum} +in it, counting from the end of the file. + +@item +-@var{linenum}:@var{columnnum} @var{file} +Visit the specified @var{file}, then go to line number @var{linenum}, +counting from the end of the file, and put point at column number +@var{columnnum}. + @item -l @var{file} @opindex -l @itemx --load=@var{file} diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 29c0bed19c..240d408a10 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2011,10 +2011,12 @@ emacsclient Options @end example @noindent -The @samp{+@var{line}} or @samp{+@var{line}:@var{column}} arguments +The @samp{+@var{line}}, @samp{+@var{line}:@var{column}}, +@samp{+-@var{line}} or @samp{+-@var{line}:@var{column}} arguments specify line numbers, or line and column numbers, for the next file -argument. These behave like the command line arguments for Emacs -itself. @xref{Action Arguments}. +argument. With a negative line number, the actual line is counted +from the end of the file. These behave like the command line +arguments for Emacs itself. @xref{Action Arguments}. The other optional arguments recognized by @command{emacsclient} are listed below: diff --git a/doc/man/emacs.1.in b/doc/man/emacs.1.in index 7b2b553979..90025a93af 100644 --- a/doc/man/emacs.1.in +++ b/doc/man/emacs.1.in @@ -66,18 +66,22 @@ The same as specifying .I file directly as an argument. .TP -.BI + number +.BI + \fR[-]\fPnumber Go to the line specified by .I number (do not insert a space between the "+" sign and the number). +With a negative line number, the actual line is counted +from the end of the file. This applies only to the next file specified. .TP -.BI + line:column +.BI + \fR[-]\fPline:column Go to the specified .I line and .IR column . +With a negative line number, the actual line is counted +from the end of the file. .TP .BI \-\-chdir= "directory" Change to diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1 index 83c8a366f8..53af0dad43 100644 --- a/doc/man/emacsclient.1 +++ b/doc/man/emacsclient.1 @@ -50,15 +50,16 @@ If you set the variable "server-window" to a window or a frame, "C-x Most options follow the usual GNU command line syntax, with long options starting with two dashes ("\-"). .TP -.BI + line\fR[\fP\fB:\fPcolumn\fR]\fP +.BI + \fR[-]\fPline\fR[\fP\fB:\fPcolumn\fR]\fP Go to the specified .I line and .IR column . A missing .I column -is treated as column 1. -This option applies only to the next file specified. +is treated as column 1. With a negative line number, the actual line +is counted from the end of the file. This option applies only to the +next file specified. .TP .B \-a, \-\-alternate-editor=COMMAND If the Emacs server is not running, run the specified shell command instead. diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 425db8cfac..948c1a8f0f 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -674,7 +674,7 @@ print_help_and_exit (void) message (false, "Usage: %s [OPTIONS] FILE...\n%s%s%s", progname, "\ Tell the Emacs server to visit the specified files.\n\ -Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ +Every FILE can be either just a FILENAME or [+[-]LINE[:COLUMN]] FILENAME.\n\ \n\ The following OPTIONS are accepted:\n\ -V, --version Just print version info and return\n\ @@ -2083,6 +2083,7 @@ main (int argc, char **argv) if (*p == '+') { unsigned char c; + if (*(p + 1) == '-') p++; do c = *++p; while (isdigit (c) || c == ':'); diff --git a/lisp/server.el b/lisp/server.el index 553890ce29..37ccf7b9f4 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1237,7 +1237,7 @@ server-process-filter ;; -position +LINE[:COLUMN]: Set point to the given ;; position in the next file. ("-position" - (if (not (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?" + (if (not (string-match "\\+\\(-?[0-9]+\\)\\(?::\\([0-9]+\\)\\)?" (car args-left))) (error "Invalid -position command in client args")) (let ((arg (pop args-left))) @@ -1437,8 +1437,13 @@ server-goto-line-column "Move point to the position indicated in LINE-COL. LINE-COL should be a pair (LINE . COL)." (when line-col - (goto-char (point-min)) - (forward-line (1- (car line-col))) + (if (>= (car line-col) 0) + (progn + (goto-char (point-min)) + (forward-line (1- (car line-col)))) + (progn + (goto-char (point-max)) + (forward-line (car line-col)))) (let ((column-number (cdr line-col))) (when (> column-number 0) (move-to-column (1- column-number)))))) diff --git a/lisp/startup.el b/lisp/startup.el index 5e0a47d3f8..7cbd7687ad 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -2570,8 +2570,13 @@ command-line-1 ;; Put the point at `line':`column' in the file ;; buffer, and reset `line' and `column' to 0. (unless (zerop line) - (goto-char (point-min)) - (forward-line (1- line))) + (if (>= line 0) + (progn + (goto-char (point-min)) + (forward-line (1- line))) + (progn + (goto-char (point-max)) + (forward-line line)))) (setq line 0) (unless (< column 1) (move-to-column (1- column))) @@ -2718,10 +2723,10 @@ command-line-1 ((equal argi "-no-desktop") (message "\"--no-desktop\" ignored because the Desktop package is not loaded")) - ((string-match "^\\+[0-9]+\\'" argi) - (setq line (string-to-number argi))) + ((string-match "^\\+\\(-?[0-9]+\\)\\'" argi) + (setq line (string-to-number (match-string 1 argi)))) - ((string-match "^\\+\\([0-9]+\\):\\([0-9]+\\)\\'" argi) + ((string-match "^\\+\\(-?[0-9]+\\):\\([0-9]+\\)\\'" argi) (setq line (string-to-number (match-string 1 argi)) column (string-to-number (match-string 2 argi)))) diff --git a/src/emacs.c b/src/emacs.c index 85102acd28..86264df7a9 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -308,8 +308,8 @@ #define MAIN_PROGRAM Action options:\n\ \n\ FILE visit FILE\n\ -+LINE go to line LINE in next FILE\n\ -+LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\ ++[-]LINE go to line LINE in next FILE\n\ ++[-]LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\ --directory, -L DIR prepend DIR to load-path (with :DIR, append DIR)\n\ --eval EXPR evaluate Emacs Lisp expression EXPR\n\ --execute EXPR evaluate Emacs Lisp expression EXPR\n\ -- 2.35.1