help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How do I highlight word at point?


From: Xah
Subject: Re: How do I highlight word at point?
Date: Sun, 19 Oct 2008 13:10:42 -0700 (PDT)
User-agent: G2/1.0

On Oct 19, 10:00 am, Nikolaj Schumacher <m...@nschum.de> wrote:
> Xah <xah...@gmail.com> wrote:
> > (defun select-word ()
> > "Select a word under cursor.
> > “word” here is considered any alphenumeric sequence with “_” or “-”."
> >  (interactive)
> >  (let (b1 b2)
> >    (skip-chars-backward "-_A-Za-z0-9")
> >    (setq b1 (point))
> >    (skip-chars-forward "-_A-Za-z0-9")
> >    (setq b2 (point))
> >    (set-mark b1)
> >    )
> >  )
>
> Why not use syntactic tables to determine what a word is?  That way it
> would work for non-English languages and use less code.
>
> (defun mark-current-word ()
>   "Place the region around the word at point."
>   (interactive)
>   (forward-word 1)
>   (mark-word -1))
>
> I think I'll also use this (replacing M-@).  But it should still be able
> to grow the region... Let's see:
>
> (defun mark-current-word (arg &optional incremental)
>   "Place the region around the word at point.
> ARG determines how many following words to include.  When INCREMENTAL is
> non-nil, extend the existing region."
>   (interactive (list (prefix-numeric-value current-prefix-arg)
>                      (or (and transient-mark-mode mark-active)
>                          (eq last-command this-command))))
>   (and incremental
>        (> (* (signum arg) (- (mark) (point))) 0)
>        (exchange-point-and-mark))
>   (forward-word arg)
>   (unless incremental
>     (mark-word (- arg))))
>
> (global-set-key "\M-@" 'mark-current-word)
>
> (improvements welcome)

Hi Nik, i have some struggling thoughts about this.

here's what i would want to have ideally:

press a key, expand selection to the current word, press again, expand
to the next semantic unit (with respect to the current lang/mode),
press again, expand further.

This idea is borrowed from Mathematica's IDE (aka the Front End).
I have wrote full description of this feature, see:

http://xahlee.org/emacs/syntax_tree_walk.html

I have a draft version for over a year now:

(defun mark-semantic-unit ()
"Select a semantic unit.
Select a word under cursor. “word” here means alphanumeric sequence
plus “_” or “-”.

When this function is run for the first time and there is no active
region,
then it selects the current word (i.e. sequence of alphanumerics plus
hyphen or underscore).
When the function is run again, or if there is a region, it extends
the
selection to the next level of enclosing delimiters."
 (interactive)
 (require 'thingatpt)
(let ((deactivate-mark nil))
(if
    (or (and (eq last-command this-command))
        (and transient-mark-mode mark-active))

    (let ((e1 (region-beginning))  (e2 (region-end)) b1 b2)
      (goto-char (- e1 0))
      (skip-chars-backward "^<>(“{[「«\"‘")
      (setq b1 (point))
      (goto-char (+ e2 0))
      (skip-chars-forward "^<>)”}]」»\"’")
      (setq b2 (point))
      (set-mark b1)
    )

  (cond
   ( (looking-at "\\_<")
    (setq pt (point))
    (push-mark pt nil t)
    (forward-symbol 1)
    )
   (t
    (forward-symbol -1)
    (setq pt (point))
    (push-mark pt nil t)
    (forward-symbol 1)
    )
   )
  )
)
)

this version works when your cursor is inside a matching pair. For
example, if your cursor is at A in:
(something here A and that)

then invoke twice it'll select the whole paren.

However, it doesn't work when the cursor is in a screwed nested
position. For example:

(something here A (and) that)

if your cursor is at A, invoke twice won't get the whole outer paren,
because the code doesn't track nested parens, it only looks for chars
in a dumb way.

Ideally, this mark-semantic-unit should just extend a semantic unit,
where what's considered a semantic unit depends on the language. But
this i imagine would be rather a non-trivial problem. I am not sure
emacs's syntax table system is rich enough to be used for this.

So, taking a step back, i tried to have the code just extending to
outer matching pairs. (effectively a extend-semantic-unit for lisp) I
think now i can make this code work by using the sexp navigation
functions. I should code this soon.

If anyone can implement this, or better yet, write a proper extend-
semantic-unit for langs with C like syntax (C++,java,javascript),
that'd be a killer feature i think.

  Xah
∑ http://xahlee.org/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]